﻿Imports System.Activities.Presentation.View
Imports System.Activities.Presentation.Model
Imports System.Activities.Presentation.Hosting
Imports System.Reflection
Imports Microsoft.VisualBasic.Activities
Imports System.Activities.Presentation.Converters
Imports System.Activities

Public Class EditorService
    Implements IExpressionEditorService


#Region "変数"

    Friend Property IntellisenseData As TreeNodes
    Friend Property EditorKeyWord As String = ""

    Private editorInstances As New Dictionary(Of String, EditorInstance)
#End Region

    Public Sub CloseExpressionEditors() Implements IExpressionEditorService.CloseExpressionEditors
        For Each chidlEditor In editorInstances.Values
            RemoveHandler chidlEditor.LostAggregateFocus, AddressOf LostFocus
            chidlEditor = Nothing
        Next
        editorInstances.Clear()
    End Sub

    Public Function CreateExpressionEditor(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem, variables As System.Collections.Generic.List(Of ModelItem), text As String) As IExpressionEditorInstance Implements IExpressionEditorService.CreateExpressionEditor
        Return CreateExpressionEditorPrivate(assemblies, importedNamespaces, variables, text, Nothing, Nothing)
    End Function

    Public Function CreateExpressionEditor(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem, variables As System.Collections.Generic.List(Of ModelItem), text As String, expressionType As System.Type) As IExpressionEditorInstance Implements IExpressionEditorService.CreateExpressionEditor
        Return CreateExpressionEditorPrivate(assemblies, importedNamespaces, variables, text, expressionType, Nothing)
    End Function

    Public Function CreateExpressionEditor(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem, variables As System.Collections.Generic.List(Of ModelItem), text As String, expressionType As System.Type, initialSize As System.Windows.Size) As IExpressionEditorInstance Implements IExpressionEditorService.CreateExpressionEditor
        Return CreateExpressionEditorPrivate(assemblies, importedNamespaces, variables, text, expressionType, initialSize)
    End Function

    Public Function CreateExpressionEditor(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem, variables As System.Collections.Generic.List(Of ModelItem), text As String, initialSize As System.Windows.Size) As IExpressionEditorInstance Implements IExpressionEditorService.CreateExpressionEditor
        Return CreateExpressionEditorPrivate(assemblies, importedNamespaces, variables, text, Nothing, initialSize)
    End Function

    Public Sub UpdateContext(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem) Implements IExpressionEditorService.UpdateContext

    End Sub


#Region "内部メソッド"

    Private _intellisenseLock As New Object
    Private Function CreateUpdatedIntellisense(ByVal vars As List(Of ModelItem)) As TreeNodes
        Dim result As TreeNodes = IntellisenseData
        SyncLock _intellisenseLock
            For Each vs In vars
                Dim vsProp = vs.Properties("Name")
                If vsProp Is Nothing Then Continue For
                Dim varName = vsProp.ComputedValue
                Dim res = From x In result.Nodes
                               Where x.Name = varName
                               Select x

                If res.FirstOrDefault Is Nothing Then
                    Dim sysType As Type = Nothing
                    Dim sysTypeProp = vs.Properties("Type")
                    If sysTypeProp IsNot Nothing Then
                        sysType = CType(sysTypeProp.ComputedValue, Type)
                    End If
                    Dim newVar As New TreeNodes With {
                        .Name = varName,
                        .ItemType = TreeNodes.NodeTypes.Primitive,
                        .SystemType = sysType,
                        .Description = ""
                    }
                    result.Nodes.Add(newVar)
                End If
            Next
        End SyncLock
        Return result
    End Function

    Private Function CreateExpressionEditorPrivate(assemblies As AssemblyContextControlItem, importedNamespaces As ImportedNamespaceContextItem, variables As System.Collections.Generic.List(Of ModelItem), text As String, expressionType As System.Type, initialSize As System.Windows.Size) As IExpressionEditorInstance
        Dim editor = New EditorInstance With {
            .IntellisenceList = Me.CreateUpdatedIntellisense(variables),
            .HighlightWords = Me.EditorKeyWord,
            .ExpressionType = expressionType,
            .Guid = Guid.NewGuid,
            .Text = text
        }
        AddHandler editor.LostAggregateFocus, AddressOf LostFocus

        editorInstances.Add(editor.Guid.ToString, editor)
        Return editor
    End Function

    Private Sub LostFocus(ByVal sender As Object, ByVal e As EventArgs)
        Dim edt = TryCast(sender, TextBox)
        If edt IsNot Nothing Then DesignerView.CommitCommand.Execute(edt.Text)
    End Sub

#End Region


End Class
